#include "stdafx.h"
#include "memorygame.h"
#include "QGraphicsItemQuestion.h"
#include "qgraphicsitemquestionfullscreen.h"
#include "qgraphicsitemtopic.h"
#include "playerwidget.h"
#include "correctiondialog.h"
#include "Windows.h"

#define BASE_ITEM_WIDTH 300
#define BASE_ITEM_HEIGHT 100
// ms

#define TIMER_INTERVAL 100
#define TIME_FOR_ANSWER 5000 
#define TIMER_LOOP_COUNT ( TIME_FOR_ANSWER / TIMER_INTERVAL )
// 3000 / 100 - timer interval

QString playersString[] = { "First", "Second", "Third" };

MemoryGame::MemoryGame( const QVector<Topic> & topicVector, const QVector<int> & questionValues, int playersCount, QWidget * parent, Qt::WFlags flags )
:   QMainWindow( parent, flags ),
    m_topicVector( topicVector ),
    m_fullScreenQuestion( NULL ),
    m_timer( this ),
    m_pressedKey( 0 ),
    m_timerValue( 0 )
{
    ui.setupUi( this );
    connect( & m_timer, SIGNAL( timeout() ), this, SLOT( onTimer() ) );

    QRect r( ui.frameGraphics->rect() );
    m_graphicsScene = new QGraphicsScene( r );
    m_graphicsView = new QGraphicsView( m_graphicsScene, ui.frameGraphics );
    m_graphicsView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
    m_graphicsView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
    m_graphicsView->setGeometry( r );
    addPlayers( playersCount );
    addItems( questionValues );
    m_graphicsView->show();
}

MemoryGame::~MemoryGame()
{

}

void MemoryGame::resizeEvent( QResizeEvent * event )
{
    QRect r( rect() );
    m_graphicsScene->setSceneRect( r );
    m_graphicsView->setGeometry( r );
    if (m_fullScreenQuestion->isVisible())
        m_fullScreenQuestion->setRect( r );

    QMainWindow::resizeEvent( event );
}

void MemoryGame::addPlayers( int playersCount )
{
    for (int i = 0; i < playersCount; i ++)
    {
        PlayerWidget * playerWidget = new PlayerWidget( this, playersString[ i ] );
        m_playerWidgetVector.push_back( playerWidget );
        ui.horizontalLayout->addWidget( playerWidget );
    }
}

void MemoryGame::addItems( const QVector<int> & questionValues )
{
    m_fullScreenQuestion = new QGraphicsItemQuestionFullScreen( 0, 0, 0, 0, * this );
    m_graphicsScene->addItem( m_fullScreenQuestion );
    m_fullScreenQuestion->hide();
    m_fullScreenQuestion->setZValue( 0.1 );

    QRect r = rect();
    int width = r.width() / m_topicVector.count();
    if (width > BASE_ITEM_WIDTH)
        width = BASE_ITEM_WIDTH;

    int height = r.height() / ( m_topicVector.begin()->questionVector.count() + 1 );
    if (height > BASE_ITEM_HEIGHT)
        height = BASE_ITEM_HEIGHT;

    int posX = 0;
    int posY = 0;

    QVector<Topic>::const_iterator it;
    FOREACH (it, m_topicVector)
    {
        m_graphicsScene->addItem( new QGraphicsItemTopic( posX, 0, width, height, * this, it->name ) );

        int posYTemp = posY;
        posYTemp += height;
        QVector<Question>::const_iterator iter;
        QVector<int>::const_iterator itr = questionValues.begin();
        FOREACH (iter, it->questionVector)
        {
            Question question = * iter;
            question.value = * itr;
            QGraphicsItemQuestion * item = new QGraphicsItemQuestion( posX, posYTemp, width, height, * this, * iter );
            //  QGraphicsItemQuestion * item = new QGraphicsItemQuestion( posX, posYTemp, width, height, * this, question );
            m_graphicsScene->addItem( item );
            posYTemp += height;
            itr ++;
        }

        posX += width;
    }
}

void MemoryGame::openQuestion( Question & question  )
{
    QRect r = rect();
    m_currentQuestion = question;
    m_fullScreenQuestion->setQuestionMode( true );
    m_fullScreenQuestion->setQuestion( question );
    m_fullScreenQuestion->show();

    int step = 10;
    int width = 0;
    int height = 0;
    int widthAdd = r.width() / step;
    int heightAdd = r.height() / step;

    int i = 0;
    while (i <= step)
    {
        int offsetX = 0;
        int offsetY = 0;
        if (i < step)
        {
            offsetX = ( r.width() / 2 ) - ( width / 2 );
            offsetY = ( r.height() / 2 ) - ( height / 2 );
            width += widthAdd;
            height += heightAdd;
        }
        else
        {
            width = r.width();
            height = r.height();
        }

        m_fullScreenQuestion->setRect( r.x() + offsetX, r.y() + offsetY, width, height );
        m_graphicsScene->update();
        Sleep( 40 );
        QApplication::processEvents();
        i ++;
    }

    m_pressedKey = 0;
    m_timerValue = 0;
    ui.progressBar->setValue( 0 );
    m_timer.start( TIMER_INTERVAL );
}

void MemoryGame::keyPressEvent( QKeyEvent * event )
{
    int key = event->key();

    if (key == Qt::Key_F2)
    {
        CorrectionDialog correctionDialog( playerScoreVector(), this );
        if (correctionDialog.exec() == QDialog::Accepted)
        {
            setPlayersScore( correctionDialog.playersScoreVector() );
            return;
        }
    }

    if (m_currentQuestion.answered == QuestionStatus::OkAnswered || 
        m_currentQuestion.answered == QuestionStatus::BadAnswered)
    {
        m_pressedKey = 0;
        m_timerValue = 0;
        ui.progressBar->setValue( 0 );
        m_fullScreenQuestion->hide();
        return;
    }

    switch (key)
    {
    case Qt::Key_1:
    case Qt::Key_2:
    case Qt::Key_3:
        m_pressedKey = key;
        break;

    case Qt::Key_Z:
        m_pressedKey = key;
        executeAnswer( false );
        m_timerValue = 0;
        ui.progressBar->setValue( 0 );
        break;

    case Qt::Key_M:
        m_pressedKey = key;
        executeAnswer( true );
        break;

    default:
        break;
    }
}

void MemoryGame::onTimer()
{ 
    switch (m_pressedKey)
    {
    case Qt::Key_1:
        pressedPlayerKey( 0 );
        break;

    case Qt::Key_2:
        pressedPlayerKey( 1 );
        break;

    case Qt::Key_3:
        pressedPlayerKey( 2 );
        break;

    default:
        break;
    }

    m_timerValue ++;
    ui.progressBar->setValue( ( 100 * m_timerValue ) / TIMER_LOOP_COUNT );
    if (m_timerValue == TIMER_LOOP_COUNT)
    {
        m_timer.stop();
        setQuestionStatus( QuestionStatus::BadAnswered );
        m_fullScreenQuestion->setQuestionMode( false );
        m_timerValue = 0;
        ui.progressBar->setValue( 0 );
    }
}

void MemoryGame::pressedPlayerKey( int playerIndex )
{
    if (m_blockedPlayerIndexes.find( playerIndex ) == m_blockedPlayerIndexes.end())
    {
        PlayerWidget * playerWidget = m_playerWidgetVector.at( playerIndex );
        playerWidget->setBackroundSelected( true );
        m_timer.stop();
    }
}

void MemoryGame::executeAnswer( bool rightAnswer )
{
    for (int i = 0; i < m_playerWidgetVector.count(); i ++)
    {
         PlayerWidget * playerWidget = m_playerWidgetVector.at( i );
         if (playerWidget->isSelected())
         {
             int value = m_currentQuestion.value;
             m_pressedKey = 0;
             if (rightAnswer)
             {
                 playerWidget->setScore( value );
                 setQuestionStatus( QuestionStatus::OkAnswered );
                 m_fullScreenQuestion->setQuestionMode( false );
             }
             else
             {
                 m_blockedPlayerIndexes.insert( i );
                 playerWidget->setScore( - value );
                 m_timer.start( TIMER_INTERVAL );
             }

             playerWidget->setBackroundSelected( false );
         }
    }
}

void MemoryGame::setQuestionStatus( QuestionStatus::Enum questionStatus )
{
    m_blockedPlayerIndexes.clear();
    m_currentQuestion.answered = questionStatus;
    QList< QGraphicsItem * >::const_iterator it;
    QList< QGraphicsItem * > itemList = m_graphicsScene->items();
    FOREACH (it, itemList)
    {
        QGraphicsItem * itema = * it;
        QGraphicsItemQuestion * item = dynamic_cast< QGraphicsItemQuestion * >( itema );
        if (item != NULL && item->questionId() == m_currentQuestion.id)
        {
            item->setQuestionStatus( questionStatus );
            return;
        }
    }
}

QVector<int> MemoryGame::playerScoreVector() const
{
    QVector<int> scoreVector;
    QVector< PlayerWidget * >::const_iterator it;
    FOREACH (it, m_playerWidgetVector)
    {
        scoreVector.push_back( (*it)->score() );
    }

    return scoreVector;
}

void MemoryGame::setPlayersScore( const QVector<int> & playerScoreVector )
{
    QVector< PlayerWidget * >::const_iterator it;
    QVector<int>::const_iterator iter = playerScoreVector.begin();
    FOREACH (it, m_playerWidgetVector)
    {
        (*it)->setAbsolutScore( * iter );
        iter ++; 
    }
}
